package it.koutifaris.travianmap.ui.animation;

import static it.koutifaris.testforclassutils.IsTestForAssert.assertIsTestFor;

import java.util.concurrent.CountDownLatch;

import junit.framework.Assert;
import android.test.AndroidTestCase;
import android.util.Log;

public class AnimatorTest extends AndroidTestCase {

	private Animator animator;
	private TestAnimation animation;
	private CountDownLatch signal;

	@Override
	protected void setUp() throws Exception {
		animation = new TestAnimation();
		animator = new Animator(new TestScheduler(), animation);
	}

	public void testPkgAndName() {
		assertIsTestFor(Animator.class);
	}

	public void testInitCalledOnce() throws Exception {
		animator.start();

		waitForAnimationEnd();

		Assert.assertEquals(1, animation.initCount);
	}

	public void testUpdateCalledNtimes() throws Exception {
		animator.start();

		waitForAnimationEnd();

		Assert.assertEquals(TestAnimation.NUM_CYCLES, animation.updateCount);
	}

	public void testUpdateTotalTime() throws Exception {
		animator.start();

		waitForAnimationEnd();

		Assert.assertTrue(TestAnimation.NUM_CYCLES * animation.getUpdateRate() <= animation.totalTime);
	}

	public void testPaintCalledMoreThanNtimes() throws Exception {
		animator.start();

		waitForAnimationEnd();

		Assert.assertTrue(TestAnimation.NUM_CYCLES <= animation.paintCount);
	}

	private void waitForAnimationEnd() throws InterruptedException {
		initSignal();
		signal.await();
	}

	private void initSignal() {
		signal = new CountDownLatch(1);
	}

	private class TestAnimation implements Animation {

		private final String TAG = TestAnimation.class.getName();

		private static final int UPDATE_RATE = 100;
		private static final int NUM_CYCLES = 10;
		private int updateCount;
		private int paintCount;
		private int initCount = 0;
		private long totalTime;
		private long start;

		@Override
		public void init() {
			updateCount = 0;
			paintCount = 0;
			initCount++;
		}

		@Override
		public void paint(float alpha) {
			paintCount++;

			if (start == 0) {
				start = System.nanoTime();
			}

			Log.i(TAG, "paint " + alpha);
		}

		@Override
		public void update(long totalTime, long deltaTime) {
			updateCount++;

			Log.i(TAG, "update: tot: " + totalTime + ",  deltaTime: " + deltaTime);
		}

		@Override
		public int getUpdateRate() {
			return UPDATE_RATE;
		}

		@Override
		public boolean isRunning() {
			boolean isRunning = updateCount < NUM_CYCLES;

			if (!isRunning) {
				totalTime = (System.nanoTime() - start) / 1000000;
				signal.countDown();
			}

			return isRunning;
		}

		@Override
		public void stopped(long totalTime, long deltaTime) {
		}

	}
}
